﻿using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Security;
using System.Text;
using System.Text.RegularExpressions;
using System.Web;

using Telerik.Sitefinity.Model;
using Telerik.Sitefinity.Modules.Pages;
using Telerik.Sitefinity.Modules.Libraries;
using Telerik.Sitefinity.Modules.News;
using Telerik.Sitefinity.Pages.Model;
using Telerik.Sitefinity.Modules.Events;
using Telerik.Sitefinity.Modules.Blogs;
using Telerik.Sitefinity.Modules.GenericContent;
using Telerik.Sitefinity.GenericContent.Model;

namespace Migration.Classes
{
	public class MigrationUrlRewriter
	{
		private static ContentManager m_ContentManager;
		private static NewsManager m_NewsManager;
		private static BlogsManager m_BlogsManager;
		private static EventsManager m_EventsManager;
		private static LibrariesManager m_LibrariesManager;
		private static PageManager m_PageManager;

		static MigrationUrlRewriter()
		{
			m_ContentManager = ContentManager.GetManager(MigrationSettings.GenericContentProvider);
			m_NewsManager = NewsManager.GetManager(MigrationSettings.NewsProvider);
			m_BlogsManager = BlogsManager.GetManager(MigrationSettings.BlogsProvider);
			m_EventsManager = EventsManager.GetManager(MigrationSettings.EventsProvider);
			m_LibrariesManager = LibrariesManager.GetManager(MigrationSettings.LibrariesProvider);
			m_PageManager = PageManager.GetManager();
		}

		public static string RewriteAlbumUrls(string source)
		{
			if (m_LibrariesManager.Provider == null)
			{
				m_LibrariesManager = LibrariesManager.GetManager(MigrationSettings.LibrariesProvider);
			}

			MatchCollection imageTags = Regex.Matches(source, @"src=""~\/Libraries\/(.*?)\/(.*?)\.sflb\.ashx"""); // ? is for "non-greedy"
			for (int i = 0; i < imageTags.Count; i++)
			{
				string libraryName = imageTags[i].Groups[1].Value.ToLowerInvariant().Replace('_', '-');
				string imageName = imageTags[i].Groups[2].Value.ToLowerInvariant().Replace('_', '-');

				var checkLibrary = m_LibrariesManager.GetAlbums().ToList().Where(t => t.UrlName.Contains(libraryName)).FirstOrDefault();
				if (checkLibrary != null)
				{
					var images = checkLibrary.Images;
					foreach (var ii in images)
					{
						if (ii.UrlName.Contains(imageName))
						{
							string newPath = String.Format("src=\"{0}\"", ii.GetThumbnailUrl().Replace(".tmb", String.Empty));
							source = source.Replace(imageTags[i].Groups[0].Value, newPath);
							break;
						}
					}
				}
			}

			return source;
		}

		public static string RewriteGenericContentItemsUrls()
		{
			if (m_ContentManager.Provider == null)
			{
				m_ContentManager = ContentManager.GetManager(MigrationSettings.GenericContentProvider);
			}

			var currentCulture = System.Threading.Thread.CurrentThread.CurrentUICulture;
			var contentItems = m_ContentManager.GetItems<ContentItem>().Where(c => c.Status == ContentLifecycleStatus.Live);

			foreach (var contentItem in contentItems)
			{
				for (int i = 0; i < contentItem.AvailableLanguages.Length; i++)
				{
					var language = contentItem.AvailableLanguages[i];
					if (String.IsNullOrEmpty(language))
						continue;

					System.Threading.Thread.CurrentThread.CurrentUICulture = new System.Globalization.CultureInfo(language);

					string contentItemContent = contentItem.GetString("Content", language);

					foreach (KeyValuePair<string, string> kvp in MigrationSettings.PageNameMappings)
					{
						contentItemContent = contentItemContent.Replace(kvp.Key, kvp.Value);
					}

					contentItem.SetString("Content", contentItemContent, language);
				}
			}

			m_ContentManager.SaveChanges();

			System.Threading.Thread.CurrentThread.CurrentUICulture = currentCulture;

			return "Rewriting generic content URLs... done";
		}

		public static string RewriteNewsItemsUrls()
		{
			if (m_NewsManager.Provider == null)
			{
				m_NewsManager = NewsManager.GetManager(MigrationSettings.NewsProvider);
			}

			var currentCulture = System.Threading.Thread.CurrentThread.CurrentUICulture;
			var news = m_NewsManager.GetNewsItems().Where(c => c.Status == ContentLifecycleStatus.Live);

			foreach (var newsItem in news)
			{
				for (int i = 0; i < newsItem.AvailableLanguages.Length; i++)
				{
					var language = newsItem.AvailableLanguages[i];
					if (String.IsNullOrEmpty(language))
						continue;

					System.Threading.Thread.CurrentThread.CurrentUICulture = new System.Globalization.CultureInfo(language);

					string newsContent = newsItem.GetString("Content", language);

					foreach (KeyValuePair<string, string> kvp in MigrationSettings.PageNameMappings)
					{
						newsContent = newsContent.Replace(kvp.Key, kvp.Value);
					}

					newsItem.SetString("Content", newsContent, language);
				}
			}

			m_NewsManager.SaveChanges();

			System.Threading.Thread.CurrentThread.CurrentUICulture = currentCulture;

			return "Rewriting news URLs... done";
		}

		public static string RewriteBlogItemsUrls()
		{
			if (m_BlogsManager.Provider == null)
			{
				m_BlogsManager = BlogsManager.GetManager(MigrationSettings.BlogsProvider);
			}

			var currentCulture = System.Threading.Thread.CurrentThread.CurrentUICulture;
			var blogPosts = m_BlogsManager.GetBlogPosts().Where(c => c.Status == ContentLifecycleStatus.Live);

			foreach (var blogPost in blogPosts)
			{
				for (int i = 0; i < blogPost.AvailableLanguages.Length; i++)
				{
					var language = blogPost.AvailableLanguages[i];
					if (String.IsNullOrEmpty(language))
						continue;

					System.Threading.Thread.CurrentThread.CurrentUICulture = new System.Globalization.CultureInfo(language);

					string blogPostContent = blogPost.GetString("Content", language);

					foreach (KeyValuePair<string, string> kvp in MigrationSettings.PageNameMappings)
					{
						blogPostContent = blogPostContent.Replace(kvp.Key, kvp.Value);
					}

					blogPost.SetString("Content", blogPostContent, language);
				}
			}

			m_BlogsManager.SaveChanges();

			System.Threading.Thread.CurrentThread.CurrentUICulture = currentCulture;

			return "Rewriting blogs URLs... done";
		}

		public static string RewriteEventItemsUrls()
		{
			if (m_EventsManager.Provider == null)
			{
				m_EventsManager = EventsManager.GetManager(MigrationSettings.EventsProvider);
			}

			var currentCulture = System.Threading.Thread.CurrentThread.CurrentUICulture;
			var events = m_EventsManager.GetEvents().Where(c => c.Status == ContentLifecycleStatus.Live);

			foreach (var eventItem in events)
			{
				for (int i = 0; i < eventItem.AvailableLanguages.Length; i++)
				{
					var language = eventItem.AvailableLanguages[i];
					if (String.IsNullOrEmpty(language))
						continue;

					System.Threading.Thread.CurrentThread.CurrentUICulture = new System.Globalization.CultureInfo(language);

					string eventContent = eventItem.GetString("Content", language);

					foreach (KeyValuePair<string, string> kvp in MigrationSettings.PageNameMappings)
					{
						eventContent = eventContent.Replace(kvp.Key, kvp.Value);
					}

					eventItem.SetString("Content", eventContent, language);
				}
			}

			m_EventsManager.SaveChanges();

			System.Threading.Thread.CurrentThread.CurrentUICulture = currentCulture;

			return "Rewriting events URLs... done";
		}

		public static string RewriteTemplateUrls()
		{
			if (m_PageManager.Provider == null)
			{
				m_PageManager = PageManager.GetManager();
			}

			var currentCulture = System.Threading.Thread.CurrentThread.CurrentUICulture;
			var templates = m_PageManager.GetTemplates();

			foreach (var template in templates)
			{
				if (template.MasterPage != null)
				{
					string masterPagePath = HttpContext.Current.Server.MapPath(template.MasterPage);
					string masterPageContent = MigrationUtils.GetSafeTextFileContents(masterPagePath);

					foreach (KeyValuePair<string, string> kvp in MigrationSettings.PageNameMappings)
					{
						masterPageContent = masterPageContent.Replace(kvp.Key, kvp.Value);
					}

					try
					{
						File.WriteAllText(masterPagePath, masterPageContent);
					}
					catch (IOException) { }
					catch (UnauthorizedAccessException) { }
					catch (SecurityException) { }
				}

				List<TemplateControl> oldControls = new List<TemplateControl>();
				List<TemplateControl> newControls = new List<TemplateControl>();

				for (int i = 0; i < template.Controls.Count; i++)
				{
					System.Web.UI.Control webControl = null;

					try
					{
						webControl = m_PageManager.LoadControl(template.Controls[i]);
					}
					catch { }

					if (webControl != null && webControl is Telerik.Sitefinity.Modules.GenericContent.Web.UI.ContentBlock)
					{
						var contentBlock = webControl as Telerik.Sitefinity.Modules.GenericContent.Web.UI.ContentBlock;

						string html = contentBlock.Html;
						string newHtml = html;
						if (html != null)
						{
							foreach (KeyValuePair<string, string> kvp in MigrationSettings.PageNameMappings)
							{
								newHtml = Regex.Replace(newHtml, kvp.Key.Replace("/", @"\/").Replace(".", @"\."), kvp.Value, RegexOptions.IgnoreCase);
							}

							if (html != newHtml)
							{
								var updatedBlock = new Telerik.Sitefinity.Modules.GenericContent.Web.UI.ContentBlock();
								updatedBlock.Html = newHtml;
								TemplateControl updatedControl = m_PageManager.CreateControl<TemplateControl>(updatedBlock, template.Controls[i].PlaceHolder);

								oldControls.Add(template.Controls[i]);
								newControls.Add(updatedControl);
							}
						}
					}
				}

				foreach (var oldControl in oldControls)
				{
					template.Controls.Remove(oldControl);
				}

				foreach (var newControl in newControls)
				{
					template.Controls.Add(newControl);
				}
			}

			System.Threading.Thread.CurrentThread.CurrentUICulture = currentCulture;

			return "Rewriting template URLs... done";
		}

		public static string RewritePageUrls()
		{
			if (m_PageManager.Provider == null)
			{
				m_PageManager = PageManager.GetManager();
			}

			foreach (var page in MigrationSettings.CreatedPages)
			{
				List<PageControl> oldControls = new List<PageControl>();
				List<PageControl> newControls = new List<PageControl>();

				for (int i = 0; i < page.Controls.Count; i++)
				{
					System.Web.UI.Control webControl = null;

					try
					{
						webControl = m_PageManager.LoadControl(page.Controls[i]);
					}
					catch { }

					if (webControl != null && webControl is Telerik.Sitefinity.Modules.GenericContent.Web.UI.ContentBlock)
					{
						var contentBlock = webControl as Telerik.Sitefinity.Modules.GenericContent.Web.UI.ContentBlock;

						string html = contentBlock.Html;
						string newHtml = html;
						if (html != null)
						{
							foreach (KeyValuePair<string, string> kvp in MigrationSettings.PageNameMappings)
							{
								newHtml = Regex.Replace(newHtml, kvp.Key.Replace("/", @"\/").Replace(".", @"\."), kvp.Value, RegexOptions.IgnoreCase);
							}

							if (html != newHtml)
							{
								var updatedBlock = new Telerik.Sitefinity.Modules.GenericContent.Web.UI.ContentBlock();
								updatedBlock.Html = newHtml;
								PageControl updatedControl = m_PageManager.CreateControl<PageControl>(updatedBlock, page.Controls[i].PlaceHolder);

								oldControls.Add(page.Controls[i]);
								newControls.Add(updatedControl);
							}
						}
					}
				}

				foreach (var oldControl in oldControls)
				{
					page.Controls.Remove(oldControl);
				}

				foreach (var newControl in newControls)
				{
					page.Controls.Add(newControl);
				}
			}

			m_PageManager.SaveChanges();

			return "Rewriting page URLs... done";
		}
	}
}
